#include "FFString.h"

#include "FFrame.h"

//FF_BEGIN

static const FFString kEmptyString;

FFString::FFString()
: std::string()
{
}

FFString::FFString(const FFString &p_string)
: std::string(p_string)
{
}

FFString::FFString(const FFString *p_string)
: std::string(p_string->c_str())
{    
}

FFString::FFString(const char *p_string)
: std::string(p_string)
{    
}

FFString::~FFString()
{
}

FFString &FFString::operator =(const char *p_string)
{
    assign(p_string);
    return (*this);
}

FFString &FFString::operator =(const std::string &p_string)
{
    if (this != &p_string) //check for self assignment
    {
        assign(p_string);
    }
    
    return (*this);
}

FFString &FFString::operator =(const FFString &p_string)
{
    return operator =((std::string)p_string);
}

FFString &FFString::operator +=(int &p_integer)
{
    /*stringstream v_stringStream;
    v_stringStream << (*this) << p_integer;
    assign(v_stringStream.str());
    */
    return (*this);
}

FFString &FFString::operator +(int &p_integer)
{
    return FFString(*this) += p_integer;
}

FFString::operator const char *() const
{
    return c_str();
}

bool FFString::isEqual(const FFString &p_string) const
{
    return compare(p_string) == 0;
}

bool FFString::isEqual(const char *p_string) const
{
    return compare(p_string) == 0;
}
 
int FFString::parseInt() const
{
    return atoi(c_str());
}

const char * FFString::parseCharP() const
{
    return c_str();
}

float FFString::parseFloat() const
{
    return atof(c_str());
}



FFString FFString::replaceAll(const char *p_from, const char *p_to)
{
    std::string v_from(p_from);
    std::string v_to(p_to);
    
    size_t v_stringPosition = 0;
    while((v_stringPosition = find(v_from, v_stringPosition)) != std::string::npos) 
    {
        replace(v_stringPosition, v_from.length(), v_to);
        v_stringPosition += v_to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
    }
    
    return (*this);
}

FFVector<FFString> FFString::split(const char *p_separator)
{
    FFVector<FFString> v_stringVector;
    
    FFString v_string(this);
    int v_postionToCut;
    while( (v_postionToCut = v_string.find_first_of(p_separator)) != std::string::npos )
    {
        if(v_postionToCut > 0)
        {
            v_stringVector.push_back(v_string.substr(0,v_postionToCut).c_str());
        }
        v_string = v_string.substr(v_postionToCut+1);
    }
    
    if(v_string.length() > 0)
    {
        v_stringVector.push_back(v_string);
    }
    
    return v_stringVector;
}

FFString FFString::prepareToParseVector(const char *p_separator)
{
    FFString v_stringToSplit(this);
    FFString v_separator(p_separator);
    if (!v_separator.isEqual(" "))
    {
        v_stringToSplit.replaceAll(" ", "");
    }
    
    return v_stringToSplit;
}

FFVector<float> FFString::parseVectorOfFloats(const char *p_separator)
{    
    FFString v_stringToSplit = prepareToParseVector(p_separator);
    FFVector<float> v_floatVector;
    FFVector<FFString> v_stringSplit = v_stringToSplit.split(p_separator);
    FOR_EACH_IN_VECTOR(FFString, v_token, v_stringSplit)
    {
        float v_value = v_token.parseFloat();
        v_floatVector.addItem(v_value);
    }
    
    return v_floatVector;
}

FFVector<int> FFString::parseVectorOfInts(const char *p_separator)
{    
    FFString v_stringToSplit = prepareToParseVector(p_separator);
    FFVector<int> v_intVector;
    FFVector<FFString> v_stringSplit = v_stringToSplit.split(p_separator);
    FOR_EACH_IN_VECTOR(FFString, v_token, v_stringSplit)
    {
        int v_value = v_token.parseInt();
        v_intVector.addItem(v_value);
    }
    
    return v_intVector;
}

const FFString &FFString::emptyString()
{
    return kEmptyString;
}

bool FFString::isEmpty() const
{
    return isEqual(kEmptyString);
}


//FF_END